home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-m32r / flat.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  4.4 KB  |  147 lines

  1. /*
  2.  * include/asm-m32r/flat.h
  3.  *
  4.  * uClinux flat-format executables
  5.  *
  6.  * Copyright (C) 2004  Kazuhiro Inaoka
  7.  *
  8.  * This file is subject to the terms and conditions of the GNU General Public
  9.  * License.  See the file "COPYING" in the main directory of this archive for
  10.  * more details.
  11.  */
  12. #ifndef __ASM_M32R_FLAT_H
  13. #define __ASM_M32R_FLAT_H
  14.  
  15. #define    flat_stack_align(sp)        (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
  16. #define    flat_argvp_envp_on_stack()        0
  17. #define    flat_old_ram_flag(flags)        (flags)
  18. #define    flat_set_persistent(relval, p)        0
  19. #define    flat_reloc_valid(reloc, size)        \
  20.     (((reloc) - textlen_for_m32r_lo16_data) <= (size))
  21. #define flat_get_addr_from_rp(rp, relval, flags, persistent) \
  22.     m32r_flat_get_addr_from_rp(rp, relval, (text_len) )
  23.  
  24. #define flat_put_addr_at_rp(rp, addr, relval) \
  25.     m32r_flat_put_addr_at_rp(rp, addr, relval)
  26.  
  27. /* Convert a relocation entry into an address.  */
  28. static inline unsigned long
  29. flat_get_relocate_addr (unsigned long relval)
  30. {
  31.         return relval & 0x00ffffff; /* Mask out top 8-bits */
  32. }
  33.  
  34. #define    flat_m32r_get_reloc_type(relval)    ((relval) >> 24)
  35.  
  36. #define M32R_SETH_OPCODE    0xd0c00000 /* SETH instruction code */
  37.  
  38. #define FLAT_M32R_32        0x00    /* 32bits reloc */
  39. #define FLAT_M32R_24        0x01    /* unsigned 24bits reloc */
  40. #define FLAT_M32R_16        0x02    /* 16bits reloc */
  41. #define FLAT_M32R_LO16        0x03    /* signed low 16bits reloc (low()) */
  42. #define FLAT_M32R_LO16_DATA    0x04    /* signed low 16bits reloc (low())
  43.                        for a symbol in .data section */
  44.                     /* High 16bits of an address used
  45.                        when the lower 16bbits are treated
  46.                        as unsigned.
  47.                                            To create SETH instruction only.
  48.                        0x1X: X means a number of register.
  49.                        0x10 - 0x3F are reserved. */
  50. #define FLAT_M32R_HI16_ULO    0x10    /* reloc for SETH Rn,#high(imm16) */
  51.                     /* High 16bits of an address used
  52.                        when the lower 16bbits are treated
  53.                        as signed.
  54.                                            To create SETH instruction only.
  55.                        0x2X: X means a number of register.
  56.                        0x20 - 0x4F are reserved. */
  57. #define FLAT_M32R_HI16_SLO    0x20    /* reloc for SETH Rn,#shigh(imm16) */
  58.  
  59. static unsigned long textlen_for_m32r_lo16_data = 0;
  60.  
  61. static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp,
  62.                                                         unsigned long relval,
  63.                                 unsigned long textlen)
  64. {
  65.         unsigned int reloc = flat_m32r_get_reloc_type (relval);
  66.     textlen_for_m32r_lo16_data = 0;
  67.     if (reloc & 0xf0) {
  68.         unsigned long addr = htonl(*rp);
  69.         switch (reloc & 0xf0)
  70.         {
  71.         case FLAT_M32R_HI16_ULO:
  72.         case FLAT_M32R_HI16_SLO:
  73.             if (addr == 0) {
  74.                 /* put "seth Rn,#0x0" instead of 0 (addr). */
  75.                 *rp = (M32R_SETH_OPCODE | ((reloc & 0x0f)<<24));
  76.             }
  77.             return addr;
  78.         default:
  79.             break;
  80.         }
  81.     } else {
  82.         switch (reloc)
  83.         {
  84.         case FLAT_M32R_LO16:
  85.             return htonl(*rp) & 0xFFFF;
  86.         case FLAT_M32R_LO16_DATA:
  87.                         /* FIXME: The return value will decrease by textlen
  88.                at m32r_flat_put_addr_at_rp () */
  89.             textlen_for_m32r_lo16_data = textlen;
  90.             return (htonl(*rp) & 0xFFFF) + textlen;
  91.         case FLAT_M32R_16:
  92.             return htons(*(unsigned short *)rp) & 0xFFFF;
  93.         case FLAT_M32R_24:
  94.             return htonl(*rp) & 0xFFFFFF;
  95.         case FLAT_M32R_32:
  96.             return htonl(*rp);
  97.         default:
  98.             break;
  99.         }
  100.     }
  101.     return ~0;      /* bogus value */
  102. }
  103.  
  104. static inline void m32r_flat_put_addr_at_rp (unsigned long *rp,
  105.                          unsigned long addr,
  106.                                              unsigned long relval)
  107. {
  108.         unsigned int reloc = flat_m32r_get_reloc_type (relval);
  109.     if (reloc & 0xf0) {
  110.         unsigned long Rn = reloc & 0x0f; /* get a number of register */
  111.         Rn <<= 24; /* 0x0R000000 */
  112.         reloc &= 0xf0;
  113.         switch (reloc)
  114.         {
  115.         case FLAT_M32R_HI16_ULO: /* To create SETH Rn,#high(imm16) */
  116.             *rp = (M32R_SETH_OPCODE | Rn
  117.                    | ((addr >> 16) & 0xFFFF));
  118.             break;
  119.         case FLAT_M32R_HI16_SLO: /* To create SETH Rn,#shigh(imm16) */
  120.             *rp = (M32R_SETH_OPCODE | Rn
  121.                    | (((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
  122.                   & 0xFFFF));
  123.             break;
  124.         }
  125.     } else {
  126.         switch (reloc) {
  127.         case FLAT_M32R_LO16_DATA:
  128.             addr -= textlen_for_m32r_lo16_data;
  129.             textlen_for_m32r_lo16_data = 0;
  130.         case FLAT_M32R_LO16:
  131.             *rp = (htonl(*rp) & 0xFFFF0000) | (addr & 0xFFFF);
  132.             break;
  133.         case FLAT_M32R_16:
  134.             *(unsigned short *)rp = addr & 0xFFFF;
  135.             break;
  136.         case FLAT_M32R_24:
  137.             *rp = (htonl(*rp) & 0xFF000000) | (addr & 0xFFFFFF);
  138.             break;
  139.         case FLAT_M32R_32:
  140.             *rp = addr;
  141.             break;
  142.         }
  143.     }
  144. }
  145.  
  146. #endif /* __ASM_M32R_FLAT_H */
  147.